package com.xingda.packing.dmss.minitor.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xingda.packing.dmss.appset.AppSetService;
import com.xingda.packing.dmss.common.DateTimeUtils;
import com.xingda.packing.dmss.common.PackUtils;
import com.xingda.packing.dmss.common.dto.PageDto;
import com.xingda.packing.dmss.config.ThreadLocalConfig;
import com.xingda.packing.dmss.config.appset.AppSetParam;
import com.xingda.packing.dmss.domain.PackProductionLine;
import com.xingda.packing.dmss.enums.BoxLocationNo;
import com.xingda.packing.dmss.enums.BoxTaskState;
import com.xingda.packing.dmss.enums.EQType;
import com.xingda.packing.dmss.enums.WheelType;
import com.xingda.packing.dmss.events.EventCreater;
import com.xingda.packing.dmss.http.PackingRequireHttp;
import com.xingda.packing.dmss.minitor.dto.*;
import com.xingda.packing.dmss.minitor.entity.*;
import com.xingda.packing.dmss.minitor.mapper.*;
import com.xingda.packing.dmss.minitor.service.*;
import com.xingda.packing.dmss.plc.entity.PlcItem;
import com.xingda.packing.dmss.plc.entity.PlcItemVal;
import com.xingda.packing.dmss.plc.service.PlcDirectiveService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author anxiaoning
 * @since 2021-07-03
 */
@Slf4j
@Service
public class PkTaskServiceImpl extends ServiceImpl<PkTaskMapper, PkTask> implements IPkTaskService {
    @Resource
    private PkTaskMapper pkTaskMapper;

    @Resource
    private PkBoxLocationMapper pkBoxLocationMapper;

    @Resource
    private PkBoxLocationRealtionMapper pkBoxLocationRealtionMapper;

    @Resource
    private EventCreater eventCreater;

    @Resource
    private PkTaskDemandMapper pkTaskDemandMapper;

    @Resource
    private PkWheelMapper pkWheelMapper;

    @Resource
    private PkTaskInfoMapper pkTaskInfoMapper;

    @Resource
    private PlcDirectiveService plcDirectiveService;

    @Resource
    private AppSetService appSetService;

    @Resource
    private IPkWheelService pkWheelService;

    @Resource
    private IPkTaskInfoService pkTaskInfoService;

    @Resource
    private IPkConsumerDemandService pkConsumerDemandService;

    @Resource
    private IPkTaskUploadService pkTaskUploadService;

    @Resource
    private IPkTaskBomService pkTaskBomService;

    @Resource
    private PackProductionLine packProductionLine;

    @Resource
    private IpkLogService ipkLogService;
    @Resource
    private ThreadLocalConfig threadLocalConfig;
    @Resource
    private PkPlcLogMapper pkPlcLogMapper;
    @Value("${spring.profiles.active}")
    private String env;
    @Resource
    private PkBomNameMapper pkBomNameMapper;

    @Override
    public Page<PkTaskDto> getPkTaskPage(PageDto dto) {

        if (dto.getCurrent() == 0) {
            dto.setCurrent(1);
        }
        if (dto.getPagesize() == 0) {
            dto.setPagesize(10);
        }

        Page<PkTask> page = new Page<>(dto.getCurrent(), dto.getPagesize());
        LambdaQueryWrapper<PkTask> queryWrapper = Wrappers.lambdaQuery();

        Date start = DateTimeUtils.toDate(dto.getStart());
        queryWrapper.ge(Objects.nonNull(start), PkTask::getStartTime, start);

        Date end = DateTimeUtils.toDate(dto.getEnd());
        queryWrapper.le(Objects.nonNull(end), PkTask::getStartTime, end);

        queryWrapper.like(StringUtils.hasText(dto.getKeyword()), PkTask::getTaskName, dto.getKeyword());
        queryWrapper.orderByDesc(PkTask::getStartTime);

        this.baseMapper.selectPage(page, queryWrapper);

        Page<PkTaskDto> pkTaskDtoPage = new Page<>();
        BeanUtils.copyProperties(page, pkTaskDtoPage);

        List<PkTaskDto> dtos = new ArrayList<>();
        List<PkTask> tasks = page.getRecords();

        tasks.forEach(t -> {
            PkTaskDto taskDto = new PkTaskDto();
            BeanUtils.copyProperties(t, taskDto);
            dtos.add(taskDto);
        });
        pkTaskDtoPage.setRecords(dtos);
        return pkTaskDtoPage;
    }


    @Override
    public List<PkTask> getPkTaskList(Integer id) {
        List<PkTask> tasks = this.lambdaQuery().eq(PkTask::getPlanId, id).eq(PkTask::getState, 1).list();

        if (tasks.size() > 0) {
            tasks.forEach(task -> {
                JSONObject obj = PackingRequireHttp.searchPackingBoxInspection(task.getPkPacking(), true, false, false,
                        false);
                if (!StrUtil.isEmpty(obj.getJSONObject("result").getString("packinvweigh"))) {
                    // 修改状态为已完成
                    task.setState(3);
                    task.setIsCurrentFinished(0);
                    this.updateEntity(task);
                }
            });
        }

        return this.lambdaQuery().eq(PkTask::getPlanId, id).in(PkTask::getState, 1, 4).list();
    }

    public void updateEntity(PkTask task) {
        this.updateById(task);
    }


    @Override
    public List<PkTask> getPkTaskListByLocationIds(List<Integer> ids) {
        return this.pkTaskMapper.getPkTaskListByLocationIds(ids);
    }

    @Override
    public PkTask getByBoxLocationNo(int boxLocationNo) {
        LambdaQueryWrapper<PkBoxLocation> pkBoxlocationLambdaQueryWrapper = Wrappers.lambdaQuery();
        pkBoxlocationLambdaQueryWrapper.eq(PkBoxLocation::getBoxLocationNo, boxLocationNo);
        List<PkBoxLocation> pkBoxLocationList = pkBoxLocationMapper.selectList(pkBoxlocationLambdaQueryWrapper);

        if (pkBoxLocationList == null || pkBoxLocationList.isEmpty()) {
            log.error("未查询到装箱位{}信息！", boxLocationNo);
            return null;
        }
        PkBoxLocation pkBoxLocation = pkBoxLocationList.get(0);

        LambdaQueryWrapper<PkBoxLocationRealtion> pkBoxLocationRealtionWrapper = Wrappers.lambdaQuery();
        pkBoxLocationRealtionWrapper.eq(PkBoxLocationRealtion::getBoxLocationId, pkBoxLocation.getId());
        List<PkBoxLocationRealtion> pkBoxLocationRealtionList = pkBoxLocationRealtionMapper
                .selectList(pkBoxLocationRealtionWrapper);
        if (pkBoxLocationRealtionList == null || pkBoxLocationRealtionList.isEmpty()) {
            log.error("未查询到装箱位{}关联任务信息！", boxLocationNo);
            return null;
        }
        PkBoxLocationRealtion pkBoxLocationRealtion = pkBoxLocationRealtionList.get(0);
        return pkTaskMapper.selectById(pkBoxLocationRealtion.getTaskId());
    }

    @Transactional
    @Override
    public PkBoxDetailInfoDto getScanCodeInfo(String code) {
        // 先从自定义中查询
        PkBoxDetailInfoDto pkBoxDetailInfoDto = appSetService.getPkBoxDetailInfoDto(code);
        // 如果从自定义中查询为空,则从信息中心查询
        if (Objects.isNull(pkBoxDetailInfoDto)) {
            pkBoxDetailInfoDto = getTakeUpDetailByCode(code);
        }
        return pkBoxDetailInfoDto;
    }

    @Override
    @Transactional
    public boolean save(PkBoxInfoSetInput pkBoxInfoSetInput, PkTask pkTask, List<PkBom> pkBoms, JSONArray packinglists, Integer boxLocationId, int area) {
        log.info("====进入save方法====");
        pkTask.setUpload(pkBoxInfoSetInput.isUpload());
        pkTask.setState(BoxTaskState.RUNNING.getStateId());
        pkTask.setPalletType(pkBoxInfoSetInput.getPalletType());
        pkTask.setStartTime(new Date());
        pkTask.setBoxLocationId(boxLocationId);
        pkTaskMapper.insert(pkTask);
        // 保存中筒允许装的物料
        pkTaskBomService.saveTaskBom(pkTask.getId(), pkBoms);
        // 保存或者更新装箱规则
        saveOrUpdateConsumerDemand(pkBoxInfoSetInput, pkTask.getCustomerName());
        // 保存装箱要求
        List<PkTaskDemand> pkTaskDemands = PackUtils.toPkTaskDemands(pkBoxInfoSetInput, pkTask.getId());
        if (Objects.nonNull(pkTaskDemands)) {
            pkTaskDemands.forEach(pkTaskDemand -> pkTaskDemandMapper.insert(pkTaskDemand));
        }
        PkBoxWheelDto pkBoxWheelDto = PackUtils.toPkBoxWheelDto(packinglists);
        if (Objects.nonNull(pkBoxWheelDto)) {
            List<PkBoxLayerDto> boxLayerInfos = pkBoxWheelDto.getBoxLayerInfos();
            for (PkBoxLayerDto pkBoxLayerDto : boxLayerInfos) {
                List<PkWheelLocationDto> wheeLocationlList = pkBoxLayerDto.getWheeLocationlList();
                int wheeLocationlSize = wheeLocationlList.size();
                for (int j = 0; j < wheeLocationlSize; j++) {
                    // 保存工字轮信息
                    PkWheel pkWheel = wheeLocationlList.get(j).getPkWheel();
                    pkWheel.setSurfaceLr(pkTask.getSurfaceLr());
                    pkWheelMapper.insert(pkWheel);
                    // 保存任务和工字轮关联信息
                    PkTaskInfo pkTaskInfo = new PkTaskInfo();
                    pkTaskInfo.setLayer(pkBoxLayerDto.getLayer());
                    pkTaskInfo.setPostion(j);
                    pkTaskInfo.setPutTime(new Date());
                    pkTaskInfo.setTaskId(pkTask.getId());
                    pkTaskInfo.setWheelId(pkWheel.getId());
                    pkTaskInfoMapper.insert(pkTaskInfo);
                }
            }
        }
        // 删除装箱位原关联任务信息
        LambdaQueryWrapper<PkBoxLocationRealtion> pkBoxLocationRealtionLambdaQueryWrapper = Wrappers.lambdaQuery();
        pkBoxLocationRealtionLambdaQueryWrapper.eq(PkBoxLocationRealtion::getBoxLocationId, boxLocationId);
        List<PkBoxLocationRealtion> pkBoxLocationRealtionList = pkBoxLocationRealtionMapper.selectList(pkBoxLocationRealtionLambdaQueryWrapper);
        if (!CollectionUtils.isEmpty(pkBoxLocationRealtionList)) {
            PkBoxLocationRealtion pkBoxLocationRealtion = pkBoxLocationRealtionList.get(0);
            PkTask oldPkTask = pkTaskMapper.selectById(pkBoxLocationRealtion.getTaskId());
            //如果目前执行的任务为正在运行，修改期状态为停止
            if (oldPkTask.getState() == BoxTaskState.RUNNING.getStateId()) {
                oldPkTask.setState(BoxTaskState.STOP.getStateId());
                oldPkTask.setEndTime(new Date());
                pkTaskMapper.updateById(oldPkTask);
            }
        }
        pkBoxLocationRealtionMapper.delete(pkBoxLocationRealtionLambdaQueryWrapper);
        // 保存装箱位和任务的关联信息
        PkBoxLocationRealtion pkBoxLocationRealtion = new PkBoxLocationRealtion();
        pkBoxLocationRealtion.setBoxLocationId(boxLocationId);
        pkBoxLocationRealtion.setTaskId(pkTask.getId());
        pkBoxLocationRealtion.setDt(new Date());
        pkBoxLocationRealtionMapper.insert(pkBoxLocationRealtion);
        PkBoxLocation pkBoxLocation = pkBoxLocationMapper.selectById(boxLocationId);
        if (env.startsWith("xd-prod")) {
            log.info("===== save方法 === ip:{}, port:{}, pkTask:{}",pkBoxLocation.getLedIp(), pkBoxLocation.getLedPort(), pkTask);
            sendLed(pkBoxLocation.getLedIp(), pkBoxLocation.getLedPort(), pkTask);
            PlcItem palletPhotoCategoryPlcItem = new PlcItem("托盘拍照类别", pkBoxLocation.getPalletPhotoCategory());
            PlcItem palletComingPlcItem = new PlcItem("托盘拿走信号", pkBoxLocation.getPalletComing());
            PlcItem palletWheelNum = new PlcItem("托盘类型", pkBoxLocation.getPalletWheelNumSet());

            PlcItemVal palletPhotoCategoryPlcItemVal = new PlcItemVal(palletPhotoCategoryPlcItem, Objects.requireNonNull(WheelType.getByTypeId(pkTask.getWheelTypeId())).getType());
            PlcItemVal palletComingPlcItemVal = new PlcItemVal(palletComingPlcItem, true);
            PlcItemVal palletWheelNumVal = new PlcItemVal(palletWheelNum, Integer.valueOf(pkBoxInfoSetInput.getPalletType()));

            plcDirectiveService.writeVals(palletPhotoCategoryPlcItemVal, palletComingPlcItemVal, palletWheelNumVal);

            List<PlcItemVal> pivList = new ArrayList<>();
            pivList.add(palletPhotoCategoryPlcItemVal);
            pivList.add(palletComingPlcItemVal);
            pivList.add(palletWheelNumVal);
            pkPlcLogMapper.insert(new PkPlcLog(area, pivList.toString(), new Date()));
        }
        // 清楚缓存数据
        packProductionLine.getProductArea().removeBox(pkBoxLocation.getBoxLocationNo());
        packProductionLine.getProductArea().initStatus(pkBoxLocationRealtion.getId(), 0);
        // 上传包装物信息
        int boxLocationNo = BoxLocationNo.getById(pkBoxLocation.getBoxLocationNo()).getNo();
        String operation;
        if (boxLocationId > 6) {
            eventCreater.createPackinvWeigh(pkTask, boxLocationNo, 2);
            operation = "右收线";
        } else {
            eventCreater.createPackinvWeigh(pkTask, boxLocationNo, 1);
            operation = "左收线";
        }
        UserInfo userInfo = threadLocalConfig.get();
        userInfo.setOperation(operation + "保存装箱规则:" + boxLocationNo);
        ipkLogService.saveLog(userInfo);
        threadLocalConfig.remove();
        packProductionLine.getRobot().setWorkStatus(true, area);
        return true;
    }

    private void saveOrUpdateConsumerDemand(PkBoxInfoSetInput pkBoxInfoSetInput, String consumerName) {
        PkTaskBoxDemandDto pkTaskBoxDemandDto = new PkTaskBoxDemandDto();
        BeanUtils.copyProperties(pkBoxInfoSetInput, pkTaskBoxDemandDto);
        pkConsumerDemandService.saveorUpdateDemandBy(consumerName, JSONObject.toJSONString(pkTaskBoxDemandDto));
    }

    public void sendLed(String ledIP, Integer ledPort, PkTask pkTask) {
        log.info("====进入sendLed====");
        log.info("led_anew_open:{}", AppSetParam.led_anew_open);
        if (AppSetParam.led_anew_open) {
            if (Objects.nonNull(ledIP) && Objects.nonNull(ledPort)) {
                String msg = pkTask.getTaskName() + "=== 规格 ===" + pkTask.getSpecifications();
                log.info("====msg -- led传入信息:{}", msg);
                eventCreater.createLedMessage(pkTask.getTaskName() + "=== 规格 ===" + pkTask.getSpecifications(), ledIP, ledPort);
            }
        }
    }

    /**
     * 通过中筒码查询装箱详情信息
     */
    private PkBoxDetailInfoDto getTakeUpDetailByCode(String code) {

        PkBoxDetailInfoDto pkBoxDetailInfoDto = null;
        // 装箱信息
        JSONObject packingInfoJson = PackingRequireHttp.searchPackingBoxInspection(code, false, false, false, false);
        if (Objects.nonNull(packingInfoJson) && !packingInfoJson.isEmpty()) {
            PkTaskBoxInfoDto pkTaskBoxInfoDto = PackUtils.toPkTaskBoxInfoDto(packingInfoJson);
            String vfree1 = packingInfoJson.getString("vfree1");
            PkTaskBoxDemandDto pkTaskBoxDemandDto = null;
            PkConsumerDemand pkConsumerDemand = pkConsumerDemandService.getByConsumerName(vfree1);
            if (Objects.nonNull(pkConsumerDemand)) {
                pkTaskBoxDemandDto = JSONObject.parseObject(pkConsumerDemand.getDefaultDemand(), PkTaskBoxDemandDto.class);
            }
            // 装箱工字轮信息
            JSONArray packinglists = packingInfoJson.getJSONArray("packinglists");
            PkBoxWheelDto pkBoxWheelDto = PackUtils.toPkBoxWheelDto(packinglists);

            if (Objects.nonNull(pkBoxWheelDto)) {
                List<PkBoxLayerDto> boxLayerInfos = pkBoxWheelDto.getBoxLayerInfos();
                boxLayerInfos.forEach(pkBoxLayerDto -> pkBoxLayerDto.getWheeLocationlList().forEach(wheelLocation -> wheelLocation.getPkWheel().setSurfaceLr(pkTaskBoxInfoDto.getSurfaceLr())));
            }
            pkBoxDetailInfoDto = new PkBoxDetailInfoDto();
            pkBoxDetailInfoDto.setBoxInfo(pkTaskBoxInfoDto);
            pkBoxDetailInfoDto.setBoxDemand(pkTaskBoxDemandDto);
            pkBoxDetailInfoDto.setBoxWheel(pkBoxWheelDto);
        }
        return pkBoxDetailInfoDto;
    }

    @Override
    public PkTaskDetailDto getPkTaskDetailById(int taskId) {

        PkTaskDetailDto pkTaskDetailDto = new PkTaskDetailDto();

        PkTask pkTask = this.getById(taskId);
        pkTask.setBoxDescription(null);
        pkTaskDetailDto.setTask(pkTask);
        PkTaskBoxDemandDto pkTaskBoxDemandDto = getByTaskId(pkTask.getId());
        pkTaskDetailDto.setBoxDemand(pkTaskBoxDemandDto);
        List<PkBoxLayerDto> pkBoxLayerDtos = new ArrayList<>();
        for (int i = 1; i <= pkTask.getLayer(); i++) {
            PkBoxLayerDto pkBoxLayerDto = new PkBoxLayerDto();
            pkBoxLayerDto.setLayer(i);
            pkBoxLayerDto.setWheeLocationlList(new ArrayList<>());
            pkBoxLayerDtos.add(pkBoxLayerDto);
        }
        pkTaskDetailDto.setLayerList(pkBoxLayerDtos);

        List<Integer> taskIds = Collections.singletonList(pkTask.getId());

        List<Map<String, Object>> layerList = this.pkBoxLocationMapper.getPkBoxLayerList(taskIds);
        List<PkTaskInfo> taskInfoList = this.pkTaskInfoService.lambdaQuery().in(PkTaskInfo::getTaskId, taskIds)
                .orderByAsc(PkTaskInfo::getPostion).orderByAsc(PkTaskInfo::getPutTime).list();
        List<PkWheel> wheelList = this.pkWheelService.getPkWheelByPutTime(taskIds);

        // 焊点总数
        int totalSolderCount = 0;

        for (int i = 1; i <= pkTask.getLayer(); i++) {

            PkBoxLayerDto layerDto = pkTaskDetailDto.getLayerList().get(i - 1);
            layerDto.setLayer(i);
            Map<String, Object> map = null;

            int finalI = i;
            if (!CollectionUtils.isEmpty(layerList)) {
                map = layerList.stream()
                        .filter(m -> Integer.parseInt(m.get("layer").toString()) == finalI
                                && Integer.parseInt(m.get("taskId").toString()) == pkTask.getId())
                        .findAny().orElse(null);
            }
            if (map != null) {// 填充
                int solderCount = Integer.parseInt(map.get("solder").toString());
                layerDto.setSolder(solderCount);
                layerDto.setTorqueValue(Double.parseDouble(map.get("torqueValue").toString()));
                int wheelCount = Integer.parseInt(map.get("wheelCount").toString());

                int solderJointWheelCount = 0;
                Object solderJointWheelCountObject = map.get("solderJointWheelCount");
                if (Objects.nonNull(solderJointWheelCountObject)) {
                    solderJointWheelCount = Integer.parseInt(map.get("solderJointWheelCount").toString());
                }
                layerDto.setSolderJointWheelCount(solderJointWheelCount);
                layerDto.setState(wheelCount - (pkTask.getBoxWheelSum() / pkTask.getLayer()) == 0 ? 3 : 2);
                layerDto.setStrandDeviation(Double.parseDouble(map.get("strandDeviation").toString()));

                totalSolderCount += solderCount;
            } else {
                layerDto.setState(1);
            }
            List<Integer> subIds = taskInfoList.stream()
                    .filter(ti -> ti.getTaskId().compareTo(pkTask.getId()) == 0 && ti.getLayer().compareTo(finalI) == 0)
                    .map(PkTaskInfo::getWheelId).collect(Collectors.toList());
            List<PkWheel> subList = wheelList.stream().filter(pkWheel -> subIds.contains(pkWheel.getId()))
                    .collect(Collectors.toList());

            int floorCount = pkTask.getFloorCount();
            List<PkWheelLocationDto> wheeLocationlList = toPkWheelLocationDtos(subList, floorCount);
            long anewWheelCount = wheeLocationlList.stream().map(PkWheelLocationDto::getPkWheel)
                    .filter(Objects::nonNull)
                    .filter(wheel -> EQType.ANEW.getType().equalsIgnoreCase(wheel.getEqType())).count();
            layerDto.setAnewWheelCount((int) anewWheelCount);
            wheeLocationlList.sort(Comparator.comparing(PkWheelLocationDto::getLocationNo));
            layerDto.setWheeLocationlList(wheeLocationlList);
            pkTaskDetailDto.getLayerList().set(i - 1, layerDto);
        }
        pkTaskDetailDto.setSolderCount(totalSolderCount);
        // 层上传信息
        List<PkTaskUploadDto> pkTaskUploadDtoList = pkTaskUploadService.gePkTaskUploadDtoBy(pkTask.getId());
        pkTaskDetailDto.setTaskUpload(pkTaskUploadDtoList);
        return pkTaskDetailDto;
    }

    @Override
    @Transactional
    public boolean removeWheel(RemoveInputDto removeInputDto) {
        PkTask pkTask = pkTaskMapper.selectById(removeInputDto.getTaskId());
        LambdaQueryWrapper<PkTaskInfo> pkTaskInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        pkTaskInfoLambdaQueryWrapper.eq(PkTaskInfo::getWheelId, removeInputDto.getWheelId())
                .eq(PkTaskInfo::getTaskId, removeInputDto.getTaskId());
        //查询装箱位关联信息
        LambdaQueryWrapper<PkBoxLocationRealtion> pkBoxLocationRealtionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        pkBoxLocationRealtionLambdaQueryWrapper.eq(PkBoxLocationRealtion::getTaskId, removeInputDto.getTaskId());
        //删除任务信息
        pkTaskInfoMapper.delete(pkTaskInfoLambdaQueryWrapper);
        //删除工字轮
        pkWheelMapper.deleteById(removeInputDto.getWheelId());
        //初始化
        packProductionLine.getProductArea().removeBox(pkTask.getBoxLocationId());
        packProductionLine.getProductArea().initStatus(pkBoxLocationRealtionMapper.selectOne(pkBoxLocationRealtionLambdaQueryWrapper).getId(), 0);
        UserInfo userInfo = threadLocalConfig.get();
        ipkLogService.saveLog(userInfo);
        threadLocalConfig.remove();
        return true;
    }

    private PkTaskBoxDemandDto getByTaskId(Integer taskId) {
        PkTaskBoxDemandDto pkTaskBoxDemandDto = null;
        if (Objects.nonNull(taskId)) {
            LambdaQueryWrapper<PkTaskDemand> pkTaskDemandLambdaQueryWrapper = Wrappers.lambdaQuery();
            pkTaskDemandLambdaQueryWrapper.eq(PkTaskDemand::getTaskId, taskId).orderByAsc(PkTaskDemand::getSortIndex);
            List<PkTaskDemand> pkTaskDemands = pkTaskDemandMapper.selectList(pkTaskDemandLambdaQueryWrapper);
            if (Objects.nonNull(pkTaskDemands) && !pkTaskDemands.isEmpty()) {
                pkTaskBoxDemandDto = PackUtils.toPkTaskBoxDemandDto(pkTaskDemands);
            }
        }
        return pkTaskBoxDemandDto;
    }

    private List<PkWheelLocationDto> toPkWheelLocationDtos(List<PkWheel> subList, int floorCount) {
        List<PkWheelLocationDto> wheeLocationlList = new ArrayList<>();
        for (int j = 0; j < floorCount; j++) {
            wheeLocationlList.add(null);
        }
        List<Integer> sortList = AppSetParam.wheel_sort_index;
        int subSize = (Objects.nonNull(subList) && !subList.isEmpty()) ? subList.size() : 0;

        for (int j = 0; j < floorCount; j++) {
            PkWheelLocationDto pkWheelLocationDto = new PkWheelLocationDto();
            PkWheel wheel = subSize - 1 >= j ? subList.get(j) : null;
            pkWheelLocationDto.setPkWheel(wheel);
            pkWheelLocationDto.setLocationNo(j + 1);
            int sortIndex = sortList.get(j);
            wheeLocationlList.set(sortIndex, pkWheelLocationDto);
        }
        return wheeLocationlList;
    }
}
